package com.pesking.core.sqlparser.parameter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;

import com.pesking.core.SpringBeanUtils;
import org.apache.commons.lang3.StringUtils;

import com.pesking.core.exception.SystemException;
import com.pesking.core.util.ExceptionUtils;
import com.pesking.core.util.LogUtils;
import com.pesking.core.util.OrderUtils;

/**
 * SQL参数对象
 * @author chenyunpei
 *
 */
public class SqlParameter {

	private SqlParameterProcessor processor = null;
	private String name = null;
	private String value = null;
	private List<String> fields = new ArrayList<>();
	private String innerStatement = null;

	public SqlParameter(String statement) {
		if (StringUtils.isBlank(statement)) {
			throw new SystemException("参数语句为空");
		}
		String []arr = statement.split(":");
		if (arr == null){
			throw new SystemException("参数设置格式出错,参数设置应该是第一部分是[数据类型：参数名称].....");
		}
		String strType = arr[0];
		this.processor = getSqlParameterProcessor(strType);
		if (this.processor == null) {
			throw new SystemException("参数类型【" + strType + "】找不到参数类型对象");
		}
		int len = arr.length;
		if (len > 1) {
			this.name = arr[1];
		}
		if (len > 2) {
			this.value = arr[2];
		}
		for (int i = 3 ; i < arr.length ; i++) {
			this.fields.add(arr[i]);
		}
	}
	
	public String getInnerStatement() {
		return innerStatement;
	}

	public void setInnerStatement(String innerStatement) {
		this.innerStatement = innerStatement;
	}
	
	public SqlParameterProcessor getProcessor() {
		return this.processor;
	}
		
	public String getValue()
	{
		return this.value;
	}
	
	public String getName(){
		return this.name;
	}
	
	public String getField(){
		return this.getField(1);
	}
	
	public String getField(int index){
		if (index <= 0){
			index = 1;
		}
		if (this.fields != null && this.fields.size() >= index){
			return this.fields.get(index - 1);
		}
		return null;
	}
	
	public int getFieldLength(){
		if (this.fields == null){
			return 0;
		}
		return this.fields.size();
	}
	
	private static SqlParameterProcessor getSqlParameterProcessor(String strType) {
		
		if (sqlParameterProcessors == null) {
			synchronized(SqlParameter.class) {
				if (sqlParameterProcessors == null) {					
					LogUtils.warn("开始加载sql参数处理器............");
					try {
						ServiceLoader<SqlParameterProcessor> serviceLoader = ServiceLoader.load(SqlParameterProcessor.class, Thread.currentThread().getContextClassLoader());
						List<SqlParameterProcessor> processors = new ArrayList<>();
						if (serviceLoader != null) {						
							for (SqlParameterProcessor spp : serviceLoader) {
								processors.add(spp);
							}
						}
						LogUtils.warn("本服务共找到ServiceLoader sql参数处理器数量--->" + processors.size());
						List<SqlParameterProcessor> list = SpringBeanUtils.getBeanList(SqlParameterProcessor.class);
						processors.addAll(list);
						LogUtils.warn("本服务共找到bean sql参数处理器数量--->" + list.size());
						if (processors.size() > 1) {
							OrderUtils.sortByMin(list);
						}
						
						sqlParameterProcessors = new HashMap<>();
						for (SqlParameterProcessor item : processors) {
							for (String type : item.getSqlParameterType()){
								sqlParameterProcessors.put(type.toUpperCase(), item);
							}

						}
					}
					catch(Throwable ex) {
						LogUtils.warn("加载sql参数处理器失败 ,具体原因->" + ExceptionUtils.getCauseMessage(ex));
					}
					finally {
						LogUtils.warn("加载sql参数处理器成功............数量->" + sqlParameterProcessors.size());
					}
				}
			}
		}
		
		return sqlParameterProcessors.get(strType.toUpperCase());
	}
	
	private static Map<String,SqlParameterProcessor> sqlParameterProcessors = null;
}
